<?php
namespace App\Commen;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

/**
 * 文件导出
 * Class ExportCommen
 * @package App\Commen
 */
class ExportCommen
{
    private $fileName;
    private $obj;
    private $result;    //返回值   包含成功或者失败信息
    private $savePath;  //文件保存路径
    private $title;  //文件头信息
    private $suffix; //文件后缀
    private $allPath; //文件完整路径
    private $fileType;
    /**
     * 生成文件
     * @param string $fileName
     * @param string $fileType
     * @param string $savePath
     * @return array mixed
     */
    public function createFile($fileName, $fileType, $savePath)
    {
        if (!in_array($fileType, array(1, 2))) {
            $this->error(400, "未知格式");

            return $this->result;
        }
        $this->fileName = $fileName;
        $this->savePath = $savePath;
        $this->fileType = $fileType;
        switch ($fileType) {
            case 1:
                $this->suffix = ".csv";
                $this->createCsv();
                break;
            case 2:
                $this->suffix = ".xlsx";
                $this->createExcel();
                break;
        }

        return $this->allPath;
    }

    /**
     * @param array $insertData
     * @return bool
     */
    public function insertFile($insertData)
    {
        switch ($this->fileType) {
            case 1:
                $this->insertCsv($insertData);
                break;
            case 2:
                $this->insertExcel($insertData);
                break;
        }

        return true;
    }

    /**
     * @return mixed
     */
    public function closeFile()
    {
        fclose($this->obj);

        return $this->result;
    }

    /**
     * @param array $filesName
     * @param string $zipName
     * @return string
     */
    public function createZip($filesName, $zipName) {
        $zip = new \ZipArchive();
        $zipPath = $this->savePath.$zipName.".zip";
        if ($zip->open($zipPath, \ZipArchive::OVERWRITE) !== true) {
            if ($zip->open($zipPath, \ZipArchive::CREATE) !== true) {
                $this->error("405", "生成压缩文件失败");

                return $this->result;
            };
        };
        $zip->addEmptyDir("excel"); //生成空文件夹
        foreach ($filesName as $key => $val) {
            $zip->addFile($val, "excel/".basename($val));
        };
        $zip->close();
        foreach ($filesName as $key => $val) {
            unlink($val);
        }

        return $zipPath;
    }

    /**
     * @param string $filePath
     * @return int
     */
    public function getFileSize($filePath)
    {
        return filesize($filePath);
    }

    private function createCsv()
    {
        $this->allPath = $this->savePath.$this->fileName.$this->suffix;
        $this->obj = fopen($this->allPath, 'w');
        fputcsv($this->obj, $this->title['header'], "\t");

        return true;
    }

    private function createExcel()
    {
        $this->allPath = $this->savePath.$this->fileName.$this->suffix;
        $this->obj = fopen($this->allPath, 'w');
        fputcsv($this->obj, $this->title['header'], "\t");

        return true;
    }

    /**
     * @param array $insertData
     * @return bool
     */
    private function insertExcel($insertData)
    {
        foreach ($insertData as $val) {
            $lineData = array();
            foreach ($this->title['field'] as $v) {

                    $lineData[] = iconv('utf-8', 'gbk', $val[$v]);

            }
            fputcsv($this->obj, $lineData, "\t");
        }

        return true;
    }

    /**
     * @param array $insertData
     * @return bool
     */
    private function insertCsv($insertData)
    {
        foreach ($insertData as $val) {
            $lineData = array();
            foreach ($this->title['field'] as $v) {
                $lineData[] = $val[$v];
            }
            fputcsv($this->obj, $lineData);
        }

        return true;
    }

    /**
     * @param int $pColumnIndex
     * @return mixed
     */
    public function stringFromColumnIndex($pColumnIndex = 0)
    {
        //  Using a lookup cache adds a slight memory overhead, but boosts speed
        //  caching using a static within the method is faster than a class static,
        //      though it's additional memory overhead
        static $_indexCache = array();

        if (!isset($_indexCache[$pColumnIndex])) {
            // Determine column string
            if ($pColumnIndex < 26) {
                $_indexCache[$pColumnIndex] = chr(65 + $pColumnIndex);
            } elseif ($pColumnIndex < 702) {
                $_indexCache[$pColumnIndex] = chr(64 + ($pColumnIndex / 26)).chr(65 + $pColumnIndex % 26);
            } else {
                $_indexCache[$pColumnIndex] = chr(64 + (($pColumnIndex - 26) / 676)).chr(65 + ((($pColumnIndex - 26) % 676) / 26)).chr(65 + $pColumnIndex % 26);
            }
        }

        return $_indexCache[$pColumnIndex];
    }

    /**
     * 解析title
     * @param array $title
     * @return bool
     */
    public function parsingTitle($title)
    {
        $data = array();
        foreach ($title as $key => $val) {
            $data['header'][] = iconv('utf-8', 'gbk', $val['name']);
            $data['field'][] = $key;
            $data['type'][] = $val['type'];
        }
        $this->title = $data;

        return true;
    }

    /**
     * 错误处理
     * @param $code
     * @param $message
     */
    private function error($code, $message, $e = "")
    {
        $this->result = array(
            "code" => $code,
            "message" => $message,
            "e" => $e,
        );

        return;
    }
}
